var async = require('async');
var uuid = require('node-uuid');
var BigFloat32 = require('bigfloat').BigFloat32;
//var User = require('../domain/user');
var consts = require('../util/consts');
var exp = module.exports;

exp.consts = {
    TYPE_TIME: 1,
    TYPE_RAND: 2,
    FLOOR: 2,
    APPRENTICE: 1
}

// callback util
exp.invokeCallback = function (cb) {
    if (!!cb && typeof cb == 'function') {
        cb.apply(null, Array.prototype.slice.call(arguments, 1));
    }
};

//获取数据的类型
exp.typeofData = function (data) {
    return Object.prototype.toString.call(data);
}

//生成uuid
exp.genUuid = function (seed) {
    if (seed == this.consts.TYPE_TIME) {
        return uuid.v1();
    } else {
        return uuid.v4();
    }
}

//判断是否是数字
exp.isRealNum = function (val) {
    if (val === "" || val == null) {
        return false;
    }
    if (!isNaN(val)) {
        //对于空数组和只有一个数值成员的数组或全是数字组成的字符串，isNaN返回false，例如：'123'、[]、[2]、['123'],isNaN返回false,
        //所以如果不需要val包含这些特殊情况，则这个判断改写为if(!isNaN(val) && typeof val === 'number' )
        return true;
    } else {
        return false;
    }
}

//深度拷贝一个对象
exp.deepClone = function (obj) {
    var _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone;
}

//获取一个范围内的随机整数
exp.randomNum = function (minNum, maxNum) {
    switch (arguments.length) {
        case 1:
            return parseInt(Math.random() * minNum + 1, 10);
            break;
        case 2:
            return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
            break;
        default:
            return 0;
            break;
    }
}

//获取随机分红石的比例
exp.randomJewelSeed = function () {
    var seed = (exp.randomNum(1, 2) / 10 * Math.random()) > 0.2 ? 0.2 : exp.randomNum(1, 2) / 10 * Math.random();
    return parseFloat(seed.toFixed(2)) < 0.1 ? 0.1 : parseFloat(seed.toFixed(2));
}

//获取矿层对应的名称
exp.getFloorName = function (floor) {
    var name = '';
    if (floor == 1) {
        name = 'floor_1';
    } else if (floor > 1 && floor <= 10) {
        name = 'floor_2_10';
    } else if (floor > 10 && floor <= 20) {
        name = 'floor_11_20';
    } else if (floor > 20 && floor <= 30) {
        name = 'floor_21_30';
    } else if (floor > 30 && floor <= 40) {
        name = 'floor_31_40';
    } else if (floor > 40 && floor <= 50) {
        name = 'floor_41_50';
    } else if (floor > 50 && floor <= 60) {
        name = 'floor_51_60';
    } else if (floor > 60 && floor <= 70) {
        name = 'floor_61_70';
    } else if (floor > 70 && floor <= 80) {
        name = 'floor_71_80';
    } else if (floor > 80 && floor <= 90) {
        name = 'floor_81_90';
    } else if (floor > 90 && floor <= 100) {
        name = 'floor_91_100';
    } else {
        name = 'floor_101_110';
    }
    return name;
}

//获取矿层升级至下一等级所需的金币
exp.getUpgradeMoney = function (mapInfo, currentLevel, upgradeNeed) {
    //已达满级不能升级
    return new BigFloat32(upgradeNeed * mapInfo['upgrade_increase']).toString();
}

//获取矿层初始升级所需的金币
exp.getUpgradeInitCoins = function (mapInfo, currentLevel) {
    if (currentLevel >= 2 && currentLevel <= 10) {
        return new BigFloat32(mapInfo['upgrade_need'] * Math.pow(mapInfo['level_upgrade_increase'], (currentLevel % 11) - 2)).toString();
    } else {
        return new BigFloat32(mapInfo['upgrade_need'] * Math.pow(mapInfo['level_upgrade_increase'], (currentLevel % 11) - 1)).toString();
    }
}

//获取对应等级的产金量
exp.getLevelProduct = function (mapInfo, currentLevel) {
    return new BigFloat32(mapInfo['product'] * Math.pow(mapInfo['product_increase'], (currentLevel % 26) - 1)).toString();
}

//获取对应等级的产金量bug修复版2020-05-19 10:53 顾翔
exp.getLevelProductRepair = function (mapInfo, currentLevel, currentProduct) {
    return new BigFloat32(currentProduct * mapInfo['product_increase']).toString();
}

//获取解锁对应矿层所需要的金币
exp.getOpenFloorMoney = function (mapInfo, level) {
    var floor = exp.getSingleDigit(level);
    if (level >= 2 && level <= 10) {
        return new BigFloat32(mapInfo['open'] * Math.pow(mapInfo['level_upgrade'], (floor % 11) - 2)).toString();
    } else {
        return new BigFloat32(mapInfo['open'] * Math.pow(mapInfo['level_upgrade'], (floor % 11) - 1)).toString();
    }
}

//获取对应矿层的初始产金量
exp.getOpenFloorInitProduct = function (mapInfo, level) {
    var floor = exp.getSingleDigit(level);
    if (level >= 2 && level <= 10) {
        return mapInfo['product'] * Math.pow(mapInfo['product_increase'], (floor % 11) - 2);
    } else {
        return mapInfo['product'] * Math.pow(mapInfo['product_increase'], (floor % 11) - 1);
    }
}

//获取对应楼层在10层一组的楼层中所处位置
exp.getSingleDigit = function (number) {
    var nu1 = parseInt(number % 10);
    if (nu1 > 0) {
        return nu1;
    } else {
        if (number < 100) {
            return parseInt((number % 100) / number * 10);
        } else if (number < 1000) {
            return parseInt((number % 1000) / number * 10);
        }
    }
}

//获取对应等级的矿工信息
exp.getPitManByLevel = function (pitman, level) {
    var pitinfo = exp.getPitmanVal(pitman, level);
    var key = (level % 5) - 1;
    return {
        'name': pitinfo['name'],
        'avatar': pitinfo['icon'][key]
    };
}

exp.getPitmanVal = function (pitman, level) {
    if (level <= 5) {
        return pitman[0];
    } else if (level > 5 && level <= 10) {
        return pitman[1];
    } else if (level > 10 && level <= 15) {
        return pitman[2];
    } else if (level > 15 && level <= 20) {
        return pitman[3];
    } else if (level > 20 && level <= 25) {
        return pitman[4];
    } else if (level > 25 && level <= 30) {
        return pitman[5];
    } else if (level > 30 && level <= 35) {
        return pitman[6];
    } else if (level > 35 && level <= 40) {
        return pitman[7];
    } else if (level > 40 && level <= 45) {
        return pitman[8];
    } else if (level > 45 && level <= 50) {
        return pitman[9];
    }
}

//判断用户是否是有效用户
exp.isEffectUser = function (userinfo) {
    if (userinfo.current_level >= exp.consts.FLOOR && userinfo.apprentice_num >= exp.consts.APPRENTICE) {
        return true;
    }
    return false;
}

//判断用户是否可领取红包
exp.canReceiveRed = function (userInfo) {
    return userInfo.current_level >= userInfo.nextRedPacketInfo.level_require && userInfo.apprentice_num >= userInfo.nextRedPacketInfo.apprentice_require && userInfo.disciple_num >= userInfo.nextRedPacketInfo.disciple_require;
}

//判断用户能否能否领取分红宝石
exp.openAndSaveJewel = function (floor) {
    if (parseInt(floor) == 20 || parseInt(floor) == 30 || parseInt(floor) == 40 || parseInt(floor) == 50) {
        return true;
    }
    return false;
}

//格式化用户金币
exp.formatCoins = function (coins) {
    if (coins <= 1000) {
        return parseFloat(coins).toFixed(2);
    } else if (coins > 1000 && coins < 1000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000).toString()) + 'K';
    } else if (coins >= 1000000 && coins < 1000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000).toString()) + 'M';
    } else if (coins >= 1000000000 && coins < 1000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000).toString()) + 'G';
    } else if (coins >= 1000000000000 && coins < 1000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000).toString()) + 'T';
    } else if (coins >= 1000000000000000 && coins < 1000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000).toString()) + 'a';
    } else if (coins >= 1000000000000000000 && coins < 1000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000).toString()) + 'b';
    } else if (coins >= 1e+21 && coins < 1e+24) {
        return exp.formatDecimal(new BigFloat32(coins / 1e+21).toString()) + 'c';
    } else if (coins >= 1000000000000000000000000 && coins < 1000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000).toString()) + 'd';
    } else if (coins >= 1000000000000000000000000000 && coins < 1000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000).toString()) + 'e';
    } else if (coins >= 1000000000000000000000000000000 && coins < 1000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000).toString()) + 'f';
    } else if (coins >= 1000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000).toString()) + 'g';
    } else if (coins >= 1000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000).toString()) + 'h';
    } else if (coins >= 1000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000).toString()) + 'i';
    } else if (coins >= 1000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000).toString()) + 'j';
    } else if (coins >= 1000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000).toString()) + 'k';
    } else if (coins >= 1000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000).toString()) + 'l';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000).toString()) + 'm';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000).toString()) + 'n';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000).toString()) + 'o';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000).toString()) + 'p';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000).toString()) + 'q';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'r';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 's';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 't';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'u';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'v';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'w';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'x';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'y';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'z';
    } else if (coins >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 && coins < 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'aa';
    } else {
        return exp.formatDecimal(new BigFloat32(coins / 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).toString()) + 'ab';
    }
}

//保留两位小数
exp.formatDecimal = function (coins) {
    var str = coins + '';
    if (str.indexOf('.') != -1) {
        var array = str.split('.');
        return array[0] + '.' + array[1].slice(0, 2);
    } else {
        return str;
    }
}

//获取宝箱的分配比例
exp.divideChestNumber = function (number) {
    /*
    return {
        ordinary_treasure_num: parseInt(number * 0.90),
        superior_treasure_num: parseInt(number * 0.70)
    }
    */

    return {
        ordinary_treasure_num: 1,
        superior_treasure_num: 1
    }
}

//计算秒产金量
exp.calTotalProduction = function (levelInfo) {
    let product = 0;
    if (levelInfo.length > 0) {
        for (let i = 0; i < levelInfo.length; i++) {
            product = product + parseFloat(levelInfo[i].product);
        }
    }
    return product;
}

//宝箱出现的方式
exp.chestAppearWay = function (levelInfo) {
    let seed = exp.randomNum(1, 100);
    if (seed > 50) {
        return 1; //挖矿出产
    } else {
        return 2; //天空漂浮
    }
}

/**
 * 查询徒弟助力情况
 * @param uid
 * @param callback
 * @returns {number}
 */
/*
exp.apprenticeHelpNum = function (uid, callback) {
    if (uid === null) {
        return 0;
    }
    async.waterfall([
        function (cb) {
            User.find({parent_id: uid, is_effect_user: true}, {
                uid: 1,
                nickname: 1,
                gmt_create: 1,
                is_effect_user: 1,
                current_level: 1,
                parent_id: 1,
                video_num: 1,
                avatar: 1,
            }, function (err, users) {
                if (err) {
                    cb(err, null);
                    return
                }

                let helpNum = 0;
                for (let i = 0; i < users.length; i++) {
                    if (users[i].video_num === consts.Constant.DAILY_VIDEO_TIME) {
                        helpNum += consts.Constant.APPRENTICE_FULL_HELP_NUM;
                    } else {
                        helpNum += consts.Constant.APPRENTICE_UN_FULL_HELP_NUM;
                    }
                }
                cb(null, helpNum)
            });
        }
    ], function (err, helpNum) {
        console.log("num = " + helpNum);
        callback(err, helpNum)
    });
};
*/

//解码宝箱redis超时字段
exp.decodeBoxOverTimeKey = function (key) {
    let msgSub = key.slice(11, key.length);
    let msgSubAry = msgSub.split("@");
    let uid = msgSubAry[0];
    let boxId = msgSubAry[1];
    let sid = msgSubAry[2]
    return {uid, boxId, sid}
}

//打印调用堆栈
exp.printStack = function () {
    let i = 0;
    let fun = arguments.callee;
    do {
        fun = fun.arguments.callee.caller;
        console.log(++i + ': ' + fun);
    } while (fun);
}

